package com.syf.config.feign;

import com.syf.constant.Constants;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * feign拦截器--RequestInterceptor:
 *      1.在使用feign做服务间调用的时候，如何修改请求的头部或编码信息呢，可以通过实现RequestInterceptor接口的apply方法
 *          feign在发送请求之前都会调用该接口的apply方法    [所以我们也可以通过实现该接口来记录请求发出去的时间点]
 *
 *      2.使自定义的Feign配置类生效：
 *              @FeignClient(name = "member-service",configuration = OAuth2FeignConfig.class ,path = "/users")
 *
 *      3.RequestInterceptor接口定义了apply方法，其参数为RequestTemplate；
 *
 *      4.它有一个抽象类为BaseRequestInterceptor，还有几个实现类分别为BasicAuthRequestInterceptor、FeignAcceptGzipEncodingInterceptor、FeignContentGzipEncodingInterceptor
 *          查看一个接口的实现类: Ctrl + T
 */
@Slf4j
public class OAuth2FeignConfig implements RequestInterceptor {

    /**
     * 重写RequestInterceptor接口的apply()方法，feign在发送请求之前都会调用该接口的apply方法
     */
    @Override
    public void apply(RequestTemplate template) {
        // 1.我们可以从request的上下文环境里面获取token
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        String header = null;
        if (requestAttributes == null) {
  //          log.info("没有请求的上下文,故无法进行token的传递");
            header = "bearer "+ Constants.INSIDE_TOKEN ;  //没有token,给一个客户端请求的 永不过期token它
        }else {
            HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
            header = request.getHeader(HttpHeaders.AUTHORIZATION); // 获取我们请求上下文的头里面的AUTHORIZATION
        }

        // 2.将该token传递给feign将要发起的请求(存储在请求头中),而不再是去请求一个新的token
        if (!StringUtils.isEmpty(header)) {
            template.header(HttpHeaders.AUTHORIZATION, header);
            log.info("本次token传递成功,token的值为:{}", header);
        }
    }
}


